// /**
//  * @brief      模态分析测试模板类
//  *
//  * 本测试对模型计算得到的特征值进行校核
//  *
//  * @version  0.1
//  * @author   wanghuan
//  * @date     2024.12.12
//  * _
//  * ___| |__   ___ _ __   __ _  ___  _ __   __ _
//  * / __| '_ \ / _ \ '_ \ / _` |/ _ \| '_ \ / _` |
//  * \__ \ | | |  __/ | | | (_| | (_) | | | | (_| |
//  * |___/_| |_|\___|_| |_|\__, |\___/|_| |_|\__, |
//  * |___/          |___/
//  * @copyright (c) 2024 by 神工仿真, All Rights Reserved.
//  */
#pragma once
#include <complex>
#include <memory>
#include <string>
#include <vector>

#include "gtest/gtest.h"

#include "DBManager/IService/Input/Dynamic/IEIGRLService.h"
#include "DBManager/IService/Result/Summary/IEIGENVALUEService.h"

#include "../ModalSolver.h"


using SG::DataStructure::Common::Real;
using SG::DataStructure::Common::Status;
using SG::DataStructure::FEM::Project;
using namespace SG::DBManager;
using SG::DataStructure::Post::EIGENVALUEData;

extern std::shared_ptr<DBServiceFactory> DB_SERVICEFACTORY;

template <typename T>
class ModalTestBase : public ::testing::TestWithParam<T>
{
  protected:
    void SetUp () override
    {
        const auto& para = this->GetParam ();

        std::string modelPath   = SG::Utility::FileSystem::getTestDataPath ("SGFem/ModalAnalysis/");
        project.m_modelFilePath = modelPath;
        project.m_modelFileName = para.m_inputFile;
        auto posi               = para.m_inputFile.find ('.');
        project.m_jobName       = para.m_inputFile.substr (0, posi);

        DB_SERVICEFACTORY->ClearDatabase ();
        SG::Import::SGImporter importer (DB_SERVICEFACTORY);
        auto                   status = importer.Import (project.m_modelFilePath + project.m_modelFileName);
        ASSERT_EQ (status, Status::STATUS_Success);

        // 注册单元计算类
        RegisterElementCalculator ();
    }

    void TearDown () override
    {
        DB_SERVICEFACTORY->ClearDatabase ();
    }

    Project project;
};


struct ModalAnalysisTestData
{
    std::string       m_inputFile;    ///< 输入文件名称
    std::vector<Real> m_eigenValues;  ///< 求解特征值结果
};

using RealModalTest = ModalTestBase<ModalAnalysisTestData>;

TEST_P (RealModalTest, ComputeEigenValueAsExpect)
{
    const auto& para       = GetParam ();
    auto        subcaseIds = DB_SERVICEFACTORY->get<ISubcaseService> ()->GetAllSubcaseID ();

    ModalSolver solver;
    solver.Solve (DB_SERVICEFACTORY, project, subcaseIds[0]);

    auto           dataService = DB_SERVICEFACTORY->get<IEIGENVALUEService> ();
    EIGENVALUEData eigenVData;
    for (std::size_t index = 0; index < para.m_eigenValues.size (); ++index)
    {
        dataService->Find (subcaseIds[0], index + 1, _OUT eigenVData);
        ASSERT_NEAR (eigenVData.m_EIGEN, para.m_eigenValues[index], 1.0);
    }
}

std::vector<Real> Hexa8_TwoElementEigenValue{ 7018517.9252773626, 7904171.8167319968, 12849584.504279472, 14007641.143609414,
                                              17671179.275121033, 21468557.017198753, 22606096.558926541, 30245603.142481066,
                                              30797689.102722734, 41288877.737978838 };
INSTANTIATE_TEST_SUITE_P (RealModalAnalysis,
                          RealModalTest,
                          testing::Values (ModalAnalysisTestData{ "Hexa8_TwoElement_Model.bdf", Hexa8_TwoElementEigenValue }));
